<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>str转Z字形并输出新str</title>

    <style>
        body>div {
            width: 100%;
            min-height: 30px;
            font-size: 20px;
            font-family: "Microsoft YaHei";
            font-weight: bold;
            line-height: 30px;
        }

        /* 原始字符串 */
        .originalStr {
            background-color: orange;
        }

        /* Z字形字符串 */
        .convertStr {
            background-color: purple;
        }

        /* 输出结果字符串 */
        .resultStr {
            background-color: yellowgreen;
        }
    </style>
</head>

<body>
    原始字符串：<div class="originalStr"></div>

    Z字形字符串：
    <pre><div class="convertStr"></div></pre>


    输出结果字符串：<div class="resultStr"></div>

    <script>
        /* 
        将一个给定字符串 s 根据给定的行数 numRows ，以从上往下、从左到右进行 Z 字形排列。
        比如输入字符串为 “PAYPALISHIRING” 行数为 3 时，排列如下：
            P   A   H   N
            A P L S I I G
            Y   I   R
        之后，你的输出需要从左往右逐行读取，产生出一个新的字符串比如： “PAHNAPLSIIGYIR” 。
        请你实现这个将字符串进行指定行数变换的寒暑：
            string convert(string s, int numRows);
         */

        (function () {
            var resultStr = document.getElementsByClassName("resultStr")[0];
            // 调用方法并赋值结果字符串
            resultStr.innerHTML = convert("PAYPALISHIRINGPAYPALISHIRINGPAYPALISHIRINGPAYPALISHIRING", 11);
        })();

        /* 
        思路：
            P     A     H     N
            A   P L   S I   I G
            A P   L S   I I   G
            Y     I     R

            P       A       H       N
            A     P L     S I     I G
            A   P   L   S   I   I   G
            A P     L S     I I     G
            Y       I       R

            P         A         H         N
            A       P L       S I       I G
            A     P   L     S   I     I   G
            A   P     L   S     I   I     G
            A P       L S       I I       G
            Y         I         R
            1、每一次空格数：space = 2n-1（PS：n = numRows-1），
            按 numRows-1 的倍数倒序排列
                如numRows = 4，n = 4-1 = 3
                则每一次空格数：
                    n = 3，space = 5
                    n = 2，space = 3
                    n = 1，space = 1
                按 numRows-1 = 3 的倍数倒序加空格数
                    num = 1, space = 5
                    num = 2, space = 3
                    num = 3, space = 1
                    num = 4, space = 5

                    num = 5, space = 3
                    num = 6, space = 1
                    num = 7, space = 5
                    ......
            2、每一行建立一个数组，数组个数：numRows
         */

        /* 
            实现方法
            参数：原始字符串，行数
         */
        function convert(s, numRows) {
            // 赋值原始字符串
            document.getElementsByClassName("originalStr")[0].innerHTML = s;

            // 二维数组，用于存每一行字符串
            var everyRowArr = [];
            /* 二维数组声明 */
            for (let i = 0; i < numRows; i++) {
                everyRowArr[i] = [];
            }

            // 空格数数组
            var spaceArr = [];
            /* 计算空格数数组 */
            var spaceN = numRows - 1;
            for (let i = 0; i < numRows - 1; i++) {
                spaceArr[i] = "";

                // 循环放入对应空格个数
                for (let j = 0; j < spaceN * 2 - 1; j++) {
                    spaceArr[i] += "&nbsp;"
                }
                spaceN -= 1;
            }

            /* 实现Z字形字符串 */
            // 字符串转数组
            var sArr = s.split("");
            // 控制对应空格数的index
            var spaceArrIndex = 0;
            // 控制二维数组行数的index
            var everyRowArrIndex1 = 0;

            // 判断存入二维数组的顺序是正、反序
            var flag = true;

            // 循环放入按行划分的二维数组
            sArr.map((v, i) => {
                // 放入字符、对应个数空格
                everyRowArr[everyRowArrIndex1].push(v + spaceArr[spaceArrIndex]);
                // 空格数变换
                if ((i + 1) % (numRows - 1) == 0) {
                    spaceArrIndex = 0;
                } else {
                    spaceArrIndex += 1;
                }

                // 正、反序换行
                if (everyRowArrIndex1 == numRows - 1 || ((i + 1) > numRows && everyRowArrIndex1 == 0)) {
                    flag = !flag;
                }

                // 存入二维数组的顺序
                if (flag) {
                    everyRowArrIndex1 += 1;
                } else {
                    everyRowArrIndex1 -= 1;
                }
            });

            // Z字形字符串
            var convertStr = "";
            // 结果字符串
            var resultStr = "";
            everyRowArr.map((v, i) => {
                // 去掉所有 逗号
                convertStr += v.toString().replace(/,/g, "");
                // 去掉所有 空格
                resultStr += v.toString().replace(/&nbsp;/g, "");

                if (i + 1 != everyRowArr.length) {
                    // 为Z字形字符串添加换行符
                    convertStr += "\n";
                }
            });

            // 赋值Z字形字符串
            document.getElementsByClassName("convertStr")[0].innerHTML = convertStr;

            // 输出结果字符串
            return resultStr.replace(/,/g, "");
        }
    </script>
</body>

</html>